home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
usenet
/
sources
/
volume90
/
util
/
bsindex1
/
part01
/
src
/
sort.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-02-02
|
4KB
|
148 lines
/*
* SORT.C
*
* This module contains the sorting routines that read sorting order from
* the command line, and sort the file database according to that order.
*
*/
#ifndef LATTICE_50
#include "system.h"
#endif
#include "bbsindex.h"
/*
* Arrays used to determine sorting order for SORT.
*/
int i_order[MAXINDEX+1];
int i_ascend[MAXINDEX+1];
/*
* sortcmp()
* ---------
* This function is called by qsort. It compares the two specified
* elements, and returns -ve, 0 or +ve to indicate whether the second
* record is greater than, equal or less than the first, using the
* sorting criteria defined in SORT.
*/
/*
* DOCMP is a macro which sets cmp equal to the value of the enclosed
* expression if i_ascend[i] is true, or the negative of the expression
* if i_ascend is false.
*/
#define DOCMP(x) (cmp = (i_ascend[i] ? (x) : -(x)))
int sortcmp(ptr1,ptr2)
UDHEAD **ptr1, **ptr2;
{
UDHEAD *p1 = *ptr1, *p2 = *ptr2;
int i, cmp = 0;
/*
* Note safety exit - last element of i_order is guaranteed == I_ANY
*/
for (i = 0; !cmp; i++) {
switch (i_order[i]) {
case I_ANY: return(0);
case I_ACCESS: DOCMP(p1->accesses - p2->accesses);
break;
case I_BINARY: DOCMP(p2->bin - p1->bin);
break;
case I_COMMENT: DOCMP(stricmp(p1->desc, p2->desc));
break;
case I_DISKNAME: DOCMP(stricmp(p1->disk_name, p2->disk_name));
break;
case I_SECTION: DOCMP(p1->section - p2->section);
break;
case I_ONLINE: DOCMP(p2->online - p1->online);
break;
case I_LOCAL: DOCMP(p2->local - p1->local);
break;
case I_NAME: DOCMP(strcmp(p1->cat_name, p2->cat_name));
break;
case I_OWNER: DOCMP(strcmp(p1->owner, p2->owner));
break;
case I_PATHNAME: DOCMP(strcmp(dirnames[p1->dirnum],
dirnames[p2->dirnum]));
break;
case I_DIRECTORY: DOCMP(p1->dir - p2->dir);
break;
case I_DISKDIRNUM: DOCMP(p1->dirnum - p2->dirnum);
break;
case I_VALID: DOCMP(p2->valid - p1->valid);
break;
case I_DATE: DOCMP(p1->date - p2->date);
break;
case I_SIZE: DOCMP(p1->length - p2->length);
break;
case I_KSIZE: DOCMP(BTOK(p1->length) - BTOK(p2->length));
break;
}
}
return (cmp);
}
/*
* com_sort()
* ----------
* This command sorts the file database into order, according to
* the indexes specified. Each index may be optionally followed by
* a + or - to indirect sorting direction (ascending or descending).
* There must be no space between the direction and the +/-.
*/
void com_sort()
{
char *index, *p;
int i, j;
int ascend;
CHECKDATABASE();
sorted = TRUE;
for (i = 0; i < MAXINDEX && compos < comlen; i++) {
index = getstring();
p = index + strlen(index) - 1;
/*
* Now check to see if sorting direction specified, and adjust
* string if it was. Set 'ascend' to TRUE if ascending,
* else FALSE.
*/
ascend = TRUE;
if (*p == CHAR_ASCEND || *p == CHAR_DESCEND) {
if (*p == CHAR_DESCEND)
ascend = FALSE;
*p = CHAR_NULL;
}
/*
* Now match index, and setup appropriate entry in array
*/
for (j = 0; j < MAXINDEX && strcmp(index,indexes[j].name); j++)
;
if (j == MAXINDEX) {
scripterror("unknown index ");
print2(index, "\n");
Cleanup(10);
}
i_order[i] = indexes[j].tag;
i_ascend[i] = ascend;
}
if (i == 0) {
i_order[i] = I_NAME;
i_ascend[i++] = TRUE;
}
i_order[i] = I_ANY;
/* Finally, do the sort! */
qsort(ptrblock, numrecs, sizeof(UDHEAD *), sortcmp);
}